/*
 * @Description: [工具库]
 * @Author: Iseven Monkey <iswoter@gmail.com>
 * @Date: 2023-09-20 09:23:14
 * @LastEditors: Iseven Monkey <iswoter@gmail.com>
 * @LastEditTime: 2024-01-22 16:21:23
 */

// 引入moment
import moment from "moment";

// moment 中文语言包
moment.defineLocale("zh-cn", {
  // 相对时间设置
  relativeTime: {
    future: "%s内",
    past: "%s前",
    s: "几秒",
    m: "1分钟",
    mm: "%d分钟",
    h: "1小时",
    hh: "%d小时",
    d: "1天",
    dd: "%d天",
    M: "1个月",
    MM: "%d个月",
    y: "1年",
    yy: "%d年",
  },
});

/**
 * @description:  获取今天时间信息
 * @return {Object}
 */
export function today() {
  return {
    date: moment().format("YYYY-MM-DD"), // 日期
    time: moment().format("HH:mm:ss"), // 时间
    datetime: moment().format("YYYY-MM-DD HH:mm:ss"), // 日期时间
    timestamp: moment().format("X"), // 时间戳
    datestamp: moment(moment().format("YYYY-MM-DD")).format("X"), // 日期时间戳
  };
}

//时间格式化
/**
 * @description:  时间格式化
 * @param {*} value 时间戳或日期时间
 * @param {*} format 格式化字符串
 * @return {String} 返回格式化后的时间
 */
export function dateFormat(value, format = "YYYY-MM-DD HH:mm") {
  return moment(value).format(format);
}

/**
 * @description:  时间距离现在
 * @param {*} value 时间戳或日期时间
 * @return {String} 返回时间距离现在的描述， 如：几秒前、几分钟前、几小时前、几天前、几个月前、几年前
 */
export function fromNow(value) {
  return moment(value).fromNow();
}

/**
 * @description: 判断是否是微信公众号
 * @return {Boolean} 返回布尔值
 */
export function isWechatOA() {
  return navigator.userAgent.toLowerCase().indexOf("micromessenger") !== -1;
}

/**
 * @description:  判断是否是微信小程序
 * @return {Boolean} 返回布尔值
 */
export function isWechatMiniProgram() {
  return navigator.userAgent.toLowerCase().indexOf("miniprogram") !== -1;
}

/**
 * @description:  将数字转换成中文数字
 * @param {Number|String} num
 * @return {String} 返回中文数字
 */
export function numToChinese(num) {
  const arr1 = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
  const arr2 = [
    "",
    "十",
    "百",
    "千",
    "万",
    "十",
    "百",
    "千",
    "亿",
    "十",
    "百",
    "千",
    "万",
    "十",
    "百",
    "千",
    "亿",
  ];
  if (!num || isNaN(num)) return "零";
  const english = num.toString().split("");
  let result = "";
  for (let i = 0; i < english.length; i++) {
    const des_i = english.length - 1 - i; // 倒序排列设值
    result = arr2[i] + result;
    const arr1_index = english[des_i];
    result = arr1[arr1_index] + result;
  }
  result = result.replace(/零(千|百|十)/g, "零").replace(/十零/g, "十"); // 将【零千、零百】换成【零】 【十零】换成【十】
  result = result.replace(/零+/g, "零"); // 合并中间多个零为一个零
  result = result.replace(/零亿/g, "亿").replace(/零万/g, "万"); // 将【零亿】换成【亿】【零万】换成【万】
  result = result.replace(/亿万/g, "亿"); // 将【亿万】换成【亿】
  result = result.replace(/零+$/, ""); // 移除末尾的零
  // 将【一十】换成【十】
  result = result.replace(/^一十/g, "十");
  return result;
}

// 数字简化
/**
 * @description:  数字简化
 * @param {Number|String} number
 * @return {String} 返回中文数字, 如：1.2万、1.2亿、1.2万亿
 */
export function simplifyNum(number) {
  number = Number(number) || 0;
  if (!number && number != 0) return number;

  const floor = (num, fixed = 100) => {
    return Math.floor(num * fixed) / fixed;
  };

  if (number >= 1e3 && number < 1e4) {
    return `${floor(number / 1e3)}千`;
  } else if (number >= 1e4 && number < 1e6) {
    return `${floor(number / 1e4)}万`;
  } else if (number >= 1e6 && number < 1e7) {
    //百万
    return `${floor(number / 1e4)}万`;
  } else if (number >= 1e7 && number < 1e8) {
    //千万
    return `${floor(number / 1e8)}亿`;
  } else if (number >= 1e8 && number < 1e10) {
    return `${floor(number / 1e8)}亿`;
  } else if (number >= 1e10 && number < 1e11) {
    //百亿
    return `${floor(number / 1e8)}亿`;
  } else if (number >= 1e11 && number < 1e12) {
    return `${floor(number / 1e11)}千亿`;
  } else if (number >= 1e12 && number < 1e13) {
    return `${floor(number / 1e11)}万亿`;
  } else if (number > 1e13) {
    return `${floor(number / 1e13)}亿亿`;
  } else {
    //一千以下
    return number;
  }
}

/**
 * @description: 针对Uniapp的富文本内容进行格式化
 * @param {String} content
 * @return {String} 返回格式化后的内容
 */
export function contentFormat(content) {
  return content.replace(/\n/g, "<br/>");
}

/**
 * @description: 内容缩略
 * @param {String} content 内容
 * @param {Int} length 长度
 * @return {String} 返回缩略后的内容
 */
export function contentEllipsis(content, length = 30) {
  content = String(content) || "";
  if (content.length > length) {
    return content.substr(0, length) + "...";
  } else {
    return "";
  }
}

/**
 * @description: 验证是否为手机号码
 * @param {String} mobile 手机号码
 * @return  {Boolean} 返回布尔值
 */
export function isMobile(mobile) {
  mobile = String(mobile);
  return /^1[3456789]\d{9}$/.test(mobile);
}

/**
 * @description: 验证是否为邮箱
 * @param {String} email 邮箱
 * @return  {Boolean} 返回布尔值
 */
export function isEmail(email) {
  email = String(email);
  return /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(email);
}

/**
 * @description: 验证是否为身份证号码
 * @param {String} id 身份证号码
 * @return  {Boolean} 返回布尔值
 */
export function isIdCard(idCard) {
  idCard = String(idCard);

  /**
   * 身份证15位编码规则：dddddd yymmdd xx p dddddd：6位地区编码 yymmdd: 出生年(两位年)月日，如：910215 xx:
   * 顺序编码，系统产生，无法确定 p: 性别，奇数为男，偶数为女
   *
   * 身份证18位编码规则：dddddd yyyymmdd xxx y dddddd：6位地区编码 yyyymmdd:
   * 出生年(四位年)月日，如：19910215 xxx：顺序编码，系统产生，无法确定，奇数为男，偶数为女 y: 校验码，该位数值可通过前17位计算获得
   *
   * 前17位号码加权因子为 Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ] 验证位
   * Y = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ] 如果验证码恰好是10，为了保证身份证是十八位，那么第十八位将用X来代替
   * 校验位计算公式：Y_P = mod( ∑(Ai×Wi),11 ) i为身份证号码1...17 位; Y_P为校验码Y所在校验码数组位置
   */

  // 15位和18位身份证号码的正则表达式
  var regIdCard =
    /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;

  // 如果通过该验证，说明身份证格式正确，但准确性还需计算
  if (regIdCard.test(idCard)) {
    if (idCard.length == 18) {
      var idCardWi = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2); // 将前17位加权因子保存在数组里
      var idCardY = new Array(1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2); // 这是除以11后，可能产生的11位余数、验证码，也保存成数组
      var idCardWiSum = 0; // 用来保存前17位各自乖以加权因子后的总和
      for (var i = 0; i < 17; i++) {
        idCardWiSum += idCard.substring(i, i + 1) * idCardWi[i];
      }

      var idCardMod = idCardWiSum % 11; // 计算出校验码所在数组的位置
      var idCardLast = idCard.substring(17); // 得到最后一位身份证号码

      // 如果等于2，则说明校验码是10，身份证号码最后一位应该是X
      if (idCardMod == 2) {
        if (idCardLast == "X" || idCardLast == "x") {
          //alert("恭喜通过验证啦！");
          return true;
        } else {
          //alert("身份证号码错误！");
          return false;
        }
      } else {
        // 用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
        if (idCardLast == idCardY[idCardMod]) {
          //alert("恭喜通过验证啦！");
          return true;
        } else {
          //alert("身份证号码错误！");
          return false;
        }
      }
    } else {
      return true;
    }
  } else {
    //alert("身份证格式不正确!");
    return false;
  }
}

/**
 * @description: 验证是否为银行卡号码
 * @param {String} card 银行卡号码
 * @return  {Boolean} 返回布尔值
 */
export function isBankCard(card) {
  card = String(card);
  return /^([1-9]{1})(\d{14}|\d{18})$/.test(card);
}

/**
 * @description: 在url后面添加参数
 * @param {String} url 需要处理的url
 * @param {Object|String} param 需要添加的参数，可以是对象或字符串
 * @return {String} 返回处理后的url
 */
export function urlParamExtend(url, param) {
  if (!param) return url;

  if (typeof param === "string") {
    // 将param转换为 object
    let paramObj = {};
    let paramArr = param.split("&");
    for (let i = 0; i < paramArr.length; i++) {
      let itemArr = paramArr[i].split("=");
      paramObj[itemArr[0]] = itemArr[1];
    }
    param = paramObj;
  }

  // 将url中的参数转换为 object
  let urlObj = {};
  let urlArr = url.split("?");
  if (urlArr.length > 1) {
    let paramArr = urlArr[1].split("&");
    for (let i = 0; i < paramArr.length; i++) {
      let itemArr = paramArr[i].split("=");
      urlObj[itemArr[0]] = itemArr[1];
    }
  }

  // 合并参数
  param = Object.assign({}, urlObj, param);

  // 生成新的url
  url = urlArr[0] + "?";
  for (let key in param) {
    url += encodeURIComponent(key) + "=" + encodeURIComponent(param[key]) + "&";
  }
  url = url.substr(0, url.length - 1);

  return url;
}

//从url中提取参数
/**
 * @description: 从url中提取参数
 * @param {String} url 需要处理的url
 * @return {Object} 返回参数对象
 */
export function urlParams(url) {
  let param = {};
  let urlArr = url.split("?");
  if (urlArr.length > 1) {
    let paramArr = urlArr[1].split("&");
    for (let i = 0; i < paramArr.length; i++) {
      let itemArr = paramArr[i].split("=");
      param[itemArr[0]] = itemArr[1];
    }
  }
  return param;
}

//从url中提取指定参数
/**
 * @description: 从url中提取指定参数
 * @param {String} url 需要处理的url
 * @param {String} key 参数名
 * @return {String} 返回参数值
 */
export function urlParam(url, key) {
  let param = urlParams(url);
  if (!param[key]) return "";

  return param[key];
}

//从当前url中提取参数
/**
 * @description: 从当前url中提取参数
 * @return {Object} 返回参数对象
 */

export function getLocalUrlParam(key) {
  return urlParam(window.location.href, key);
}

//判断是否是微信浏览器
/**
 * @description: 判断是否是微信浏览器
 * @return {Boolean} 返回布尔值
 */

export function isWechat() {
  return /micromessenger/.test(navigator.userAgent.toLowerCase());
}

//将数组倒序
/**
 * @description: 将数组倒序
 * @param {Array} arr 数组
 * @return {Array} 返回倒序后的数组
 */

export function reverseArr(arr) {
  return arr.reverse();
}
